package com.unboundedprime.osgisurveillance.monitor.util;

import com.unboundedprime.osgisurveillance.monitor.constant.SocketConstants;
import com.unboundedprime.osgisurveillance.monitor.exception.InvalidPortException;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.ServerSocket;

/**
 * Utility class to assist with socket operations.
 */
public class SocketUtils {
	/**
	 * Checks to see if a specific port is available.
	 * @param port the port to check for availability
	 */
	public static boolean checkPortForAvailability(final int port) throws InvalidPortException {
		if (port < SocketConstants.MIN_PORT_NUMBER || port > SocketConstants.MAX_PORT_NUMBER) {
			throw new InvalidPortException("Invalid port: " + port);
		}
		
		boolean portIsAvailable = true;

		ServerSocket ss = null;
		DatagramSocket ds = null;
		
		try {
			ss = new ServerSocket(port);
			ss.setReuseAddress(true);
			ds = new DatagramSocket(port);
			ds.setReuseAddress(true);
		} catch (IOException ex) {
			// If caught, the port was not available
			portIsAvailable = false;
		} finally {
			if (ds != null) {
				ds.close();
			}

			if (ss != null) {
				try {
					ss.close();
				} catch (IOException ex) {
					// Should never be thrown
				}
			}
		}

		return portIsAvailable;
	}

	/**
	 * Prevents the construction of a SocketUtils class.
	 */
	protected SocketUtils() {
		throw new UnsupportedOperationException("Pure utility classes may not be instantiated.");
	}
}
